unsigned long *backptr, unsigned long offset_in_l2, unsigned long l2_type)
{
unsigned long l2_backptr = l2_type & PGT_va_mask;
- BUG_ON(l2_backptr == PGT_va_unknown);
- if ( l2_backptr == PGT_va_mutable )
- return 0;
+ ASSERT(l2_backptr != PGT_va_unknown);
*backptr =
((l2_backptr >> PGT_va_shift) << L3_PAGETABLE_SHIFT) |
(offset_in_l2 << L2_PAGETABLE_SHIFT);
unsigned long *backptr, unsigned long offset_in_l2, unsigned long l2_type)
{
unsigned long l2_backptr = l2_type & PGT_va_mask;
- BUG_ON(l2_backptr == PGT_va_unknown);
-
+ ASSERT(l2_backptr != PGT_va_unknown);
*backptr = ((l2_backptr >> PGT_va_shift) << L3_PAGETABLE_SHIFT) |
(offset_in_l2 << L2_PAGETABLE_SHIFT);
return 1;
unsigned long *backptr, unsigned long offset_in_l3, unsigned long l3_type)
{
unsigned long l3_backptr = l3_type & PGT_va_mask;
- BUG_ON(l3_backptr == PGT_va_unknown);
-
+ ASSERT(l3_backptr != PGT_va_unknown);
*backptr = ((l3_backptr >> PGT_va_shift) << L4_PAGETABLE_SHIFT) |
(offset_in_l3 << L3_PAGETABLE_SHIFT);
return 1;
static inline int l3_backptr(
unsigned long *backptr, unsigned long offset_in_l4, unsigned long l4_type)
{
- unsigned long l4_backptr = l4_type & PGT_va_mask;
- BUG_ON(l4_backptr == PGT_va_unknown);
-
*backptr = (offset_in_l4 << L4_PAGETABLE_SHIFT);
return 1;
}
nx &= ~PGT_validated;
}
}
- else if ( unlikely(((nx & (PGT_pinned | PGT_count_mask)) ==
- (PGT_pinned | 1)) &&
- ((nx & PGT_type_mask) != PGT_writable_page)) )
- {
- /* Page is now only pinned. Make the back pointer mutable again. */
- nx |= PGT_va_mutable;
- }
}
while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
}
get_gpfn_from_mfn(page_to_mfn(page)));
return 0;
}
- else if ( (x & PGT_va_mask) == PGT_va_mutable )
- {
- /* The va backpointer is mutable, hence we update it. */
- nx &= ~PGT_va_mask;
- nx |= type; /* we know the actual type is correct */
- }
- else if ( ((type & PGT_va_mask) != PGT_va_mutable) &&
- ((type & PGT_va_mask) != (x & PGT_va_mask)) )
+ else
{
+ ASSERT((type & PGT_va_mask) != (x & PGT_va_mask));
#ifdef CONFIG_X86_PAE
/* We use backptr as extra typing. Cannot be unknown. */
if ( (type & PGT_type_mask) == PGT_l2_page_table )
return 0;
#endif
+ /* Fixme: add code to propagate va_unknown to subtables. */
+ if ( (type & PGT_type_mask) >= PGT_l2_page_table )
+ return 0;
/* This table is possibly mapped at multiple locations. */
nx &= ~PGT_va_mask;
nx |= PGT_va_unknown;
switch ( op.cmd )
{
case MMUEXT_PIN_L1_TABLE:
- type = PGT_l1_page_table | PGT_va_mutable;
+ case MMUEXT_PIN_L2_TABLE:
+ case MMUEXT_PIN_L3_TABLE:
+ case MMUEXT_PIN_L4_TABLE:
+ if ( (op.cmd - MMUEXT_PIN_L1_TABLE) != (CONFIG_PAGING_LEVELS - 1) )
+ break;
- pin_page:
if ( shadow_mode_refcounts(FOREIGNDOM) )
break;
+ type = PGT_root_page_table;
+
okay = get_page_and_type_from_pagenr(mfn, type, FOREIGNDOM);
if ( unlikely(!okay) )
{
break;
-#ifndef CONFIG_X86_PAE /* Unsafe on PAE because of Xen-private mappings. */
- case MMUEXT_PIN_L2_TABLE:
- type = PGT_l2_page_table | PGT_va_mutable;
- goto pin_page;
-#endif
-
- case MMUEXT_PIN_L3_TABLE:
- type = PGT_l3_page_table | PGT_va_mutable;
- goto pin_page;
-
- case MMUEXT_PIN_L4_TABLE:
- type = PGT_l4_page_table | PGT_va_mutable;
- goto pin_page;
-
case MMUEXT_UNPIN_TABLE:
if ( shadow_mode_refcounts(d) )
break;
/* Get the L2 index at which this L1 p.t. is always mapped. */
l2_idx = page->u.inuse.type_info & PGT_va_mask;
- if ( unlikely(l2_idx >= PGT_va_unknown) )
+ if ( unlikely(l2_idx == PGT_va_unknown) )
goto emulate; /* Urk! This L1 is mapped in multiple L2 slots! */
l2_idx >>= PGT_va_shift;
/* The 11 most significant bits of virt address if this is a page table. */
#define PGT_va_shift 16
#define PGT_va_mask (((1U<<11)-1)<<PGT_va_shift)
- /* Is the back pointer still mutable (i.e. not fixed yet)? */
-#define PGT_va_mutable (((1U<<11)-1)<<PGT_va_shift)
/* Is the back pointer unknown (e.g., p.t. is mapped at multiple VAs)? */
-#define PGT_va_unknown (((1U<<11)-2)<<PGT_va_shift)
+#define PGT_va_unknown (((1U<<11)-1)<<PGT_va_shift)
#elif defined(__x86_64__)
/* The 27 most significant bits of virt address if this is a page table. */
#define PGT_va_shift 32
#define PGT_va_mask ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
- /* Is the back pointer still mutable (i.e. not fixed yet)? */
-#define PGT_va_mutable ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
/* Is the back pointer unknown (e.g., p.t. is mapped at multiple VAs)? */
-#define PGT_va_unknown ((unsigned long)((1U<<28)-2)<<PGT_va_shift)
+#define PGT_va_unknown ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
#endif
/* 16-bit count of uses of this frame as its current type. */